package com.example.secondhandspringboot.task;

import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.example.secondhandspringboot.constant.GoodsConstant;
import com.example.secondhandspringboot.constant.RedisConstant;
import com.example.secondhandspringboot.domain.entity.RequiredGoods;
import com.example.secondhandspringboot.domain.entity.School;
import com.example.secondhandspringboot.domain.vo.GoodsVO;
import com.example.secondhandspringboot.mapper.GoodsMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatterBuilder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
@Slf4j
@AllArgsConstructor
public class TaskProject {


    private final GoodsMapper goodsMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 每日0点自动更新商品优选列表
     * 每日0点刷新增加热力值限制
     */
//    @Scheduled(cron = "0 * * * * ?")
    @Scheduled(cron = "0 0 0 * * ?")
    public void Task1() {
        log.info("定时任务更新每日优选商品执行...."+ LocalDateTime.now());
        //获取所有学校id
        for (Long schoolId : Db.list(School.class).stream().map(School::getId).toList()) {
            //随机获取20个商品
            List<GoodsVO> goodsVOList = goodsMapper.getRecommendGoodsBySchoolId(schoolId, GoodsConstant.RECOMMEND_GOODS_NUM);
            redisTemplate.delete(RedisConstant.RECOMMEND_GOODS + schoolId);
            redisTemplate.opsForValue().set(RedisConstant.RECOMMEND_GOODS + schoolId, goodsVOList);
        }

        long delNums = deleteKeysWithPrefix(RedisConstant.HEATING_VALUE);
        log.info("定时任务刷新增加热力值限制,共删除"+delNums+"条数据。"+ LocalDateTime.now());
    }




    /**
     * 每个星期一0点自动重置热力值
     */
    @Scheduled(cron = "0 0 0 * * 1")
    public void Task2(){
        log.info("每个星期一0点自动重置热力值执行"+ LocalDateTime.now());
        Db.lambdaUpdate(RequiredGoods.class)
                .set(RequiredGoods::getHeatingValue,0)
                .update();
    }




    /**
     * 定时删除缓存中的category和quality，防止数据不一致
     * 每小时执行一次
     */
    //    @Scheduled(cron = "0 * * * * ?")
    @Scheduled(cron = "0 0 0/1 * * ? ")
    public void deleteCategoryAndQuality(){
        log.info("定时任务:删除categoryCache、qualityCache"+ LocalDateTime.now());
        deleteKeysWithPrefix("categoryCache");
        deleteKeysWithPrefix("qualityCache");
    }


    /**
     * 删除指定前缀及其下的所有键。
     *
     * @param prefix 要删除的键前缀
     * @return 被删除的键数量
     */
    public long deleteKeysWithPrefix(String prefix) {
        ScanOptions scanOptions = ScanOptions.scanOptions()
                .match(prefix + "*") // 设置匹配前缀的模式
                .build();

        Cursor<String> cursor = stringRedisTemplate.scan(scanOptions);
        Set<String> keysToDelete = new HashSet<>();

        try {
            while (cursor.hasNext()) {
                keysToDelete.add(cursor.next());
            }
        } finally {
            cursor.close();
        }

        return stringRedisTemplate.delete(keysToDelete);
    }
}
